/*********************************************************************
 * Copyright (C) 2008 by Duncan A. Buell.  All rights reserved.
 * Interface for the DLL class.
 *
 * @author Duncan A. Buell
 * @version 1.00 2008-12-16
**/
public class DLL implements IDLL
{
/*********************************************************************
 * Instance variables for this class.
 * Again we include the variables for guidance purposes.
**/
    private int size;        /** list size, counting head and tail */
    private DLLNode head;    /** the head node of the list         */
    private DLLNode tail;    /** the tail node of the list         */

/*********************************************************************
 * Constructor.
 * I will let you worry about the constructor.
**/

    public DLL(){
    	this.size=2;
    	this.head =new DLLNode();
    	this.tail =new DLLNode();
    	head.setNext(tail);
		tail.setPrev(head);
    }
/*********************************************************************
 * Accessors and mutators.
**/
/*********************************************************************
 * Method to get the <code>head</code>.
 *
 * @return the node that is the value of <code>head</code>.
**/
  public DLLNode getHead(){
	  return head;
  }

/*********************************************************************
 * Method to set the <code>head</code>.
 *
 * @param value the value to be used
**/
  public void setHead(DLLNode value){
	  head=value;
  }

/*********************************************************************
 * Method to get the <code>size</code>.
 *
 * @return the value of <code>size</code>.
**/
  public int getSize(){
	  return size;
  }

/*********************************************************************
 * Method to set the <code>size</code>.
 *
 * @param value the value to be used
**/
  public void setSize(int value){
	  size=value;
  }

/*********************************************************************
 * Method to get the <code>tail</code>.
 *
 * @return the node that is the value of <code>tail</code>.
**/
  public DLLNode getTail(){
	  return tail;
  }

/*********************************************************************
 * Method to set the <code>tail</code>.
 *
 * @param value the value to be used
**/
  public void setTail(DLLNode value){
	  tail=value;
  }

/*********************************************************************
 * General methods.
**/
/*********************************************************************
 * Method to add a node.
 * By default this adds the node at the head.
 * We deliverately fail to bulletproof w.r.t. the return value.
 *
 * @param dllData the <code>T</code> data item to add.
**/
  public boolean add(Record dllData){
	 
	  DLLNode newNode = new DLLNode();
	  newNode.setNodeData(dllData);
	  
	  newNode.setNext(head.getNext());
	  newNode.setPrev(head);
	  
	  
	  head.setNext(newNode);
	  newNode.getNext().setPrev(newNode);
	  this.setSize(getSize()+1);
	  return true;
	  
  }

/*********************************************************************
 * Method to find if a list has a given data item. 
 *
 * @param dllData the <code>T</code> to match against. 
 *
 * @return the <code>boolean</code> answer to the question.
**/
  public boolean contains(Record dllData){
	  DLLNode cursor = new DLLNode();
	  cursor=this.getHead();
	  
	  
	  while(cursor.getNodeData()!=null){
		  
		 
		  if(cursor.getNodeData().equals(dllData)){
			  return true;
		  }
		  cursor=cursor.getNext();
		  
		  
	  }
	  
	  return false;
	  
	  
  }

/*********************************************************************
 * Method to remove a node with a given record as data. 
 *
 * @param dllData the <code>T</code> to match against. 
 *
 * @return the <code>boolean</code> as to whether the record was
 *         found and removed or not.
**/
  public boolean remove(Record dllData){
	  DLLNode cursor = new DLLNode();
	  cursor=this.getHead();
	  //int tempSize = this.getSize();
	  
	  while(cursor!=tail){
		  
		  cursor=cursor.getNext();
		  if(cursor.getNodeData().equals(dllData)){
			  cursor.getPrev().setNext(cursor.getNext());
			  cursor.getNext().setPrev(cursor.getPrev());
			  
			  cursor.setNext(null);
			  cursor.setPrev(null);
			  this.size--;
			  return true;
		  }
		  
		 
		  
	  }
	  
	  return false;
	  
  }

/*********************************************************************
 * Method to <code>toString</code> a complete DLL, including head and
 * tail nodes.
 *
 * @return the <code>toString</code> rep'n of the entire DLL.
**/
  public String toString(){
	  DLLNode cursor = new DLLNode();
	  cursor=this.getHead();
	  int counter=1;
	  String s="";
	  
	  s+="There are "+this.getSize()+" entries \n";
	  
	  s+="Going forward \n";
	  while(cursor!=null){
		  if(cursor.getPrev()==null){
			  s+="0:Dummy Node \n";
		  }
		  else if(cursor.getNext()==null){
			  s+=this.getSize()-1 +":Dummy Node \n";
		  }
		  else{
		   s+= counter+":"+cursor.toString()+"\n";
		  counter++;
		  }
		  cursor=cursor.getNext();
	  }
	  counter = this.getSize()-2;
	  s+="\nGoing backwards \n";
	  cursor=this.getTail();
	  while(cursor!=null){
		  if(cursor.getNext()==null){
			  s+=(this.getSize()-1) +":Dummy Node \n";
		  }
		  else if(cursor.getPrev()==null){
			  s+="0:Dummy Node \n";
		  }
		  else{
			  s+= counter+":"+cursor.toString()+"\n";
			  counter--;
			  }
		  cursor=cursor.getPrev();
			  
		  }
	  
	  
	  return s;
  }
  

} // public interface IDLL
